home *** CD-ROM | disk | FTP | other *** search
/ Supercompiler 1997 / SUPERCOMPILER97.iso / BC++ Builder / DATA.Z / APP.CPP < prev    next >
Encoding:
C/C++ Source or Header  |  1997-02-10  |  45.7 KB  |  1,469 lines

  1. //---------------------------------------------------------------------------
  2. // Borland C++Builder
  3. // Copyright (c) 1987, 1997 Borland International Inc.  All Rights Reserved.
  4. //---------------------------------------------------------------------------
  5. /* APP.CPP:  Application Expert Implementation
  6.  
  7.    012997EAS:  Added code to prevent insertion of same speedbutton
  8.                multiple times in application's speedbar (InsertClick);
  9.    013097EAS:  Code formatting adjustments
  10. */
  11.  
  12. //---------------------------------------------------------------
  13. #include <vcl\vcl.h>
  14. #pragma hdrstop
  15.  
  16. #include "app.h"              // application expert class def
  17. #include "exconst.h"          // global constants, defines
  18. #include "filters.h"          // file filter class def
  19.  
  20. #include <memory>             // for auto_ptr<>
  21. using namespace std;
  22.  
  23. //---------------------------------------------------------------
  24. #pragma resource "*.dfm"
  25. TAppExpert *AppExpert;
  26.  
  27. TPages  FirstPage          = pgMenus;
  28. TPages  LastPage           = pgAppInfo;
  29.  
  30. int     DefaultButtonSpace = 6;
  31. TPoint  DefaultButtonSize  = { 24, 24 };
  32. int     MenuItemCount      = 18;
  33. int     MenuItemCounts[]   = { 7, 4, 3, 4 };
  34. int     MenuItemOffsets[]  = { 0, 7, 11, 14 };
  35.  
  36. char    *SampleBitmaps[]   = { "MENUDSGN",
  37.                                "EXTDSGN",
  38.                                "SPEEDDSGN",
  39.                                "INFODSGN" };
  40.  
  41. char    *cSourceBuffer;                 // code composition buffer
  42. int     SourceBufferSize   = 1024;      // max code comp bfr size
  43. char    *cCodeSnipets[csLastObject-1];  // code sniptes ptr array
  44. char    *cResourceBuffer;               // code snipet strings
  45. THandle *hCodeResource;
  46.  
  47. bool     snoop = false;                 // debug facility
  48.  
  49. //--- CONSTRUCTOR AND DESTRUCTORS -------------------------------<<
  50.  
  51. //========================================[ TAppExpert ]=========
  52. __fastcall TAppExpert::TAppExpert(TComponent* Owner)
  53.                       :TForm(Owner)
  54. {
  55. }
  56.  
  57. //========================================[ TAppExpert ]=========
  58. __fastcall TAppExpert::TAppExpert(TComponent* AOwner, int Dummy)
  59.                       :TForm(AOwner, Dummy)
  60. {
  61. }
  62.  
  63. //========================================[ TAppExpert ]=========
  64. __fastcall TAppExpert::~TAppExpert(void)
  65. {
  66. }
  67.  
  68. //--- NOTEBOOK PAGE CONTROL -------------------------------------<<
  69.  
  70. //========================================== TAppExpert =========
  71. bool __fastcall TAppExpert::ValidateInfo(void)
  72. {
  73.   String e;
  74.  
  75.   if (AppName->Text == "")
  76.   {
  77.     e = LoadStr(sAppNameRequired);
  78.     Application->MessageBox(e.c_str(), "ERROR", mbOK);
  79.     return false;
  80.   }
  81.   if (!IsValidIdent(AppName->Text))
  82.   {
  83.     e = LoadStr(sInvalidAppName);
  84.     Application->MessageBox(e.c_str(), "ERROR", mbOK);
  85.     return false;
  86.   }
  87.   if (!DirectoryExists(AppPath->Text))
  88.   {
  89.     e = LoadStr(sInvalidPath);
  90.     Application->MessageBox(e.c_str(), "ERROR", mbOK);
  91.     return false;
  92.   }
  93.   return true;
  94. } // end of TAppExpert::ValidateInfo()
  95.  
  96. //========================================== TAppExpert =========
  97. // Calculate which page is next based on current page/settings:
  98. //     -1 = last page
  99. //     -2 = cannot move in requested direction
  100. int __fastcall TAppExpert::NextPage(TMoveDirection Direction)
  101. {
  102.   int Result = -2;
  103.  
  104.   int CurPage = PageControl->ActivePage->PageIndex;
  105.   switch(Direction)
  106.   {
  107.     case mdNoMove:
  108.       if (CurPage == LastPage)
  109.         Result = -1;
  110.       else
  111.         Result = 0;
  112.       break;
  113.     case mdPrevious:
  114.       switch(CurPage)
  115.       {
  116.         case pgMenus: // do nothing
  117.           break;
  118.         case pgExtensions:
  119.           Result = pgMenus;
  120.           break;
  121.         case pgSpeedbar:
  122.           if (cbFileMenu->Checked)
  123.             Result = pgExtensions;
  124.           else
  125.             Result = pgMenus;
  126.           break;
  127.         case pgAppInfo:
  128.           if (HasMenus())
  129.             Result = pgSpeedbar;
  130.           else
  131.             Result = pgMenus;
  132.           break;
  133.       }
  134.       break;
  135.     case mdNext:
  136.       switch(CurPage)
  137.       {
  138.         case pgMenus:
  139.             if (cbFileMenu->Checked)
  140.               Result = pgExtensions;
  141.             else
  142.               if (HasMenus())
  143.                 Result = pgSpeedbar;
  144.               else
  145.                 Result = pgAppInfo;
  146.           break;
  147.         case pgExtensions:
  148.           Result = pgSpeedbar;
  149.           break;
  150.         case pgSpeedbar:
  151.           Result = pgAppInfo;
  152.           break;
  153.         case pgAppInfo:
  154.           Result = -1;
  155.           break;
  156.       }
  157.       break;
  158.   }
  159.   return Result;
  160. } // end of TAppExpert::NextPage()
  161.  
  162. //========================================== TAppExpert =========
  163. void __fastcall TAppExpert::NextPrevClick(TObject *Sender)
  164. {
  165.   int NewPage;
  166.  
  167.   TButton* tb = (TButton*)(Sender);
  168.   if (tb == PrevButton)
  169.     NewPage = NextPage(mdPrevious);
  170.   else
  171.     NewPage = NextPage(mdNext);
  172.  
  173.   switch(NewPage)
  174.   {
  175.     case -1:
  176.       // If we aren't going forward, allow invalid info on page...
  177.       if (tb != NextButton)
  178.         ModalResult = mrOK;
  179.       else
  180.         // ...but don't allow us to advance to next page with
  181.         // invalid info on the current page.
  182.         if (ValidateInfo())
  183.           ModalResult = mrOK;
  184.       break;
  185.     case -2:
  186.       break; // do nothing
  187.     default:
  188.  
  189.       // If we have a suitable bitmap to add to our sample
  190.       // bitmap...
  191.       if (SampleBitmaps[NewPage] != 0)
  192.       {
  193.         // ...load it, redisplay updated sample,...
  194.         SampleBmp->Handle = LoadBitmap(HInstance,
  195.                                        SampleBitmaps[NewPage]);
  196.         Sample->Invalidate();
  197.       }
  198.  
  199.       // ...update the active notebook page and...
  200.       PageControl->ActivePage = PageControl->Pages[NewPage];
  201.       break;
  202.   }
  203.  
  204.   // ...make the Notebook control buttons reflect current state.
  205.   RefreshButtons();
  206. } // end of TAppExpert::NextPrevClick()
  207.  
  208. //========================================= TAppExpert ==========
  209. void __fastcall TAppExpert::RefreshButtons(void)
  210. {
  211.   switch(NextPage(mdNoMove))
  212.   {
  213.     case -1:
  214.       NextButton->Caption = LoadStr(sFinish);
  215.       break;
  216.     case 0:
  217.       NextButton->Caption = LoadStr(sNext);
  218.       break;
  219.   }
  220.  
  221.   switch(NextPage(mdPrevious))
  222.   {
  223.     case -2:
  224.       PrevButton->Enabled = False;
  225.       break;
  226.     default:
  227.       PrevButton->Enabled = True;
  228.       break;
  229.   }
  230. } // end of TAppExpert::RefreshButtons()
  231.  
  232. //--- SPEEDBUTTON CONTROLS --------------------------------------<<
  233.  
  234. //========================================== TAppExpert =========
  235. bool __fastcall TAppExpert::HasMenus(void)
  236. {
  237.   return (cbFileMenu->Checked || cbEditMenu->Checked ||
  238.           cbWindowMenu->Checked || cbHelpMenu->Checked);
  239. } // end of TAppExpert::HasMenus()
  240.  
  241. //---------------------------------------------------------------
  242. void __fastcall RemoveItems(TList &List, TMainItems MenuIndex)
  243. {
  244.   int StartID = sMenuItemTextBase + MenuItemOffsets[MenuIndex];
  245.   int EndID = StartID + MenuItemCounts[MenuIndex];
  246.  
  247.   int i = 0;
  248.   while(i < List.Count)
  249.   {
  250.     TButtonImage* ButtonImage = (TButtonImage*)List.Items[i];
  251.     if (ButtonImage != 0 && ButtonImage->BitmapID < EndID &&
  252.         ButtonImage->BitmapID >= StartID)
  253.       List.Delete(i);
  254.     else
  255.       i++;
  256.   }
  257. } // end of TAppExpert::RemoveItems()
  258.  
  259. //========================================= TAppExpert ==========
  260. void __fastcall TAppExpert::MenuClicked(TObject *Sender)
  261. {
  262.   // Here if a menu category has been turned on/off.
  263.   for (int MenuIndex = mmFile; MenuIndex < mmHelp; ++MenuIndex)
  264.   {
  265.     bool MenuOn;
  266.     switch(MenuIndex)
  267.     {
  268.       case mmFile:
  269.         MenuOn = cbFileMenu->Checked;
  270.         break;
  271.       case mmEdit:
  272.         MenuOn = cbEditMenu->Checked;
  273.         break;
  274.       case mmWindow:
  275.         MenuOn = cbWindowMenu->Checked;
  276.         break;
  277.       case mmHelp:
  278.         MenuOn = cbHelpMenu->Checked;
  279.         break;
  280.     }
  281.  
  282.      // If a menu has been turned off...
  283.     if (!MenuOn)
  284.     {
  285.       // ...remove its speedbutton (if it has one in the list).
  286.       RemoveItems(*SpeedList, (TMainItems)MenuIndex);
  287.       FSpeedIndex = 0;
  288.     }
  289.     if (MenuList->ItemIndex == MenuIndex)
  290.       MenuListClick(this);
  291.   }
  292. } // end of TAppExpert::MenuClicked()
  293.  
  294. //========================================== TAppExpert =========
  295. // return the rectangle of the specified speedbutton or space
  296. TRect __fastcall TAppExpert::SpeedButtonRect(int Index)
  297. {
  298.   TRect Result;
  299.  
  300.   int x = 10;  // first usable position
  301.   for (int i=0; i < Index; i++)
  302.     if (SpeedList->Items[i] == NULL)
  303.       x += DefaultButtonSpace;
  304.     else
  305.       x += DefaultButtonSize.x-1;
  306.  
  307.   Result = Bounds(x, 5, DefaultButtonSize.x, DefaultButtonSize.y);
  308.  
  309.   if (Index < SpeedList->Count && SpeedList->Items[Index] == NULL)
  310.     Result.Right = Result.Left + DefaultButtonSpace;
  311.  
  312.   return Result;
  313. } // end of TAppExpert::SpeedButtonRect()
  314.  
  315. //========================================== TAppExpert =========
  316. int __fastcall TAppExpert::GetSpeedButtonCount(void)
  317. {
  318.   return SpeedList->Count;
  319. } // end of TAppExpert::GetSpeedButtonCount()
  320.  
  321. //========================================== TAppExpert =========
  322. //  Return bitmap ID of button in speedbutton list whose index
  323. //   is passed in 'Value' or -1 if the button image at that
  324. //   index is NULL.
  325. int __fastcall TAppExpert::GetSpeedButtonID(int Value)
  326. {
  327.   int Result;
  328.  
  329.   TButtonImage* ButtonImage = (TButtonImage*)SpeedList->Items[Value];
  330.   if (ButtonImage != NULL)
  331.     Result = ButtonImage->BitmapID;
  332.   else
  333.     Result = -1;
  334.  
  335.   return Result;
  336. } // end of TAppExpert::GetSpeedButtonID()
  337.  
  338. //========================================== TAppExpert =========
  339. void __fastcall TAppExpert::SpeedbarPaint(TObject *Sender)
  340. {
  341.   TButtonImage *ButtonImage;
  342.  
  343.   TRect R;
  344.   Offscreen->Canvas->Pen->Color   = (TColor)clWindowFrame;
  345.   Offscreen->Canvas->Brush->Style = bsClear;
  346.   Offscreen->Canvas->Brush->Color = Speedbar->Color;
  347.  
  348.   Offscreen->Canvas->Rectangle(1, 1, Speedbar->Width - 1,
  349.                                Speedbar->Height - 1);
  350.   Offscreen->Canvas->Pen->Color = (TColor)clBtnShadow;
  351.   TPoint p[3];
  352.   p[0].x = 0;
  353.   p[0].y = Speedbar->Height-1;
  354.   p[1].x = 0;
  355.   p[1].y = 0;
  356.   p[2].x = Speedbar->Width-1; p[2].y = 0;
  357.   Offscreen->Canvas->Polyline(p, 3);
  358.   Offscreen->Canvas->Pen->Color = (TColor)clBtnHighlight;
  359.   p[0].x = Speedbar->Width-1;
  360.   p[0].y = 0;
  361.   p[1].x = Speedbar->Width-1;
  362.   p[1].y = Speedbar->Height;
  363.   Offscreen->Canvas->Polyline(p, 2);
  364.  
  365.   // Draw the buttons in the list
  366.   int x = 10;
  367.   for (int i=0; i < SpeedList->Count; i++)
  368.   {
  369.     ButtonImage = (TButtonImage*)SpeedList->Items[i];
  370.     if (ButtonImage == NULL)
  371.     {
  372.       Offscreen->Canvas->Brush->Style = bsSolid;
  373.       Offscreen->Canvas->Brush->Color = (TColor)clBtnShadow;
  374.       R = Bounds(x + 2, 5, DefaultButtonSpace - 3,
  375.                  DefaultButtonSize.y - 2);
  376.       Offscreen->Canvas->FillRect((TRect&)R);
  377.       x += DefaultButtonSpace;
  378.     }
  379.     else
  380.     {
  381.       Offscreen->Canvas->Brush->Style = bsSolid;
  382.       ButtonImage->Draw(Offscreen->Canvas, x, 4);
  383.       x += DefaultButtonSize.x-1;
  384.     }
  385.  
  386.     if (x + (DefaultButtonSize.x * 2) > Speedbar->Width)
  387.       break;
  388.  
  389.     // draw the insertion point }
  390.     R = SpeedButtonRect(FSpeedIndex);
  391.     OffsetRect((RECT*)&R, -5, 0);
  392.     R.Top = R.Bottom + 2;
  393.     R.Bottom = R.Top + SpeedPointer->Height;
  394.     R.Right = R.Left + SpeedPointer->Width;
  395.     Offscreen->Canvas->Brush->Color = Speedbar->Color;
  396.     Offscreen->Canvas->BrushCopy((TRect&)R, SpeedPointer,
  397.                                  (TRect&)Rect(0, 0, SpeedPointer->Width,
  398.                                              SpeedPointer->Height),
  399.                                  clWhite);
  400.   }
  401.   Speedbar->Canvas->Draw(0, 0, Offscreen);
  402. } // end of TAppExpert::SpeedbarPaint()
  403.  
  404. //========================================= TAppExpert ==========
  405. // The list of menus was clicked
  406. void __fastcall TAppExpert::MenuListClick(TObject *Sender)
  407. {
  408.   if (MenuList->ItemIndex > -1)
  409.   {
  410.     long ID = sMenuItemTextBase + MenuItemOffsets[MenuList->ItemIndex];
  411.     MenuItemList->Items->BeginUpdate();
  412.     try
  413.     {
  414.       MenuItemList->Clear();
  415.  
  416.       bool MenuOn;
  417.       switch(MenuList->ItemIndex)
  418.       {
  419.         case 0:
  420.           MenuOn = cbFileMenu->Checked;
  421.           break;
  422.         case 1:
  423.           MenuOn = cbEditMenu->Checked;
  424.           break;
  425.         case 2:
  426.           MenuOn = cbWindowMenu->Checked;
  427.           break;
  428.         case 3:
  429.           MenuOn = cbHelpMenu->Checked;
  430.           break;
  431.       }
  432.  
  433.       if (MenuOn)
  434.       {
  435.         // load the list box with the buttons and text }
  436.         for (int i=0; i < MenuItemCounts[MenuList->ItemIndex]; i++)
  437.         {
  438.           int ButtonIndex = i+MenuItemOffsets[MenuList->ItemIndex];
  439.           MenuItemList->Items->AddObject(LoadStr(ID+i),
  440.                        (TObject*)ButtonList->Items[ButtonIndex]);
  441.         }
  442.       }
  443.     }
  444.     catch(...)
  445.     {
  446.     }
  447.  
  448.     MenuItemList->Items->EndUpdate();
  449.   }
  450. } // end of TAppExpert::MenuListClick()
  451.  
  452. //========================================== TAppExpert =========
  453. void __fastcall TAppExpert::DrawMenuItem(TWinControl *Control,
  454.                                          Integer Index,
  455.                                          const TRect &Rect,
  456.                                          TOwnerDrawState State)
  457. {
  458.   TRect R;
  459.   ExtTextOut((void*)MenuItemList->Canvas->Handle, R.Left, R.Top,
  460.              ETO_OPAQUE, (RECT*)&Rect, NULL, 0, NULL);
  461.  
  462.   TButtonImage*
  463.   ButtonImage = (TButtonImage*)MenuItemList->Items->Objects[Index];
  464.   ButtonImage->Draw(MenuItemList->Canvas, Rect.Left+2, Rect.Top+1);
  465.  
  466.   R = Rect;
  467.   R.Left += DefaultButtonSize.x + 2 + 4;
  468.  
  469.   char C[255];
  470.   DrawText((void*)MenuItemList->Canvas->Handle,
  471.            StrPCopy(C, MenuItemList->Items->Strings[Index]), -1,
  472.            (RECT*)&R, DT_VCENTER || DT_SINGLELINE);
  473. } // end of TAppExpert::DrawMenuItem()
  474.  
  475. //========================================== TAppExpert =========
  476. // Insert the current button into the Speedbar
  477. void __fastcall TAppExpert::InsertClick(TObject *Sender)
  478. {
  479.   // If any item in the menu items list is selected...
  480.   if (MenuItemList->ItemIndex > -1)
  481.   {
  482.     // ...get the associated button image object.
  483.     TButtonImage* ButtonImage =
  484.     (TButtonImage*)MenuItemList->Items->Objects[MenuItemList->ItemIndex];
  485.  
  486.     // Don't permit user to insert the same button multiple times.
  487.     TButtonImage *bi;
  488.     for (int i=0; i<SpeedList->Count; i++) {
  489.       bi = (TButtonImage*)SpeedList->Items[i];
  490.       if (bi != NULL && bi->BitmapID == ButtonImage->BitmapID)
  491.         return;
  492.     }
  493.  
  494.     // If insertion cursor is between buttons, insert new
  495.     // button between existing buttons...
  496.     if (FSpeedIndex < SpeedList->Count)
  497.       SpeedList->Insert(FSpeedIndex, ButtonImage);
  498.     else
  499.  
  500.       // ...otherwise just add the right of the last button.
  501.       SpeedList->Add(ButtonImage);
  502.  
  503.     FSpeedIndex++;
  504.     Speedbar->Invalidate();
  505.   }
  506. } // end of TAppExpert::InsertClick()
  507.  
  508. //========================================== TAppExpert =========
  509. // Insert a space to the right of the insertion cursor on the
  510. //   speedbar.
  511. void __fastcall TAppExpert::SpaceClick(TObject *Sender)
  512. {
  513.   if (FSpeedIndex < SpeedList->Count)
  514.     SpeedList->Insert(FSpeedIndex, NULL);
  515.   else
  516.     SpeedList->Add(NULL);
  517.  
  518.   FSpeedIndex++;
  519.   Speedbar->Invalidate();
  520. } // end of TAppExpert::SpaceClick()
  521.  
  522. //========================================== TAppExpert =========
  523. //  Remove the speedbutton to the right of the insertion cursor.
  524. void __fastcall TAppExpert::RemoveClick(TObject *Sender)
  525. {
  526.   // If insertion cursor is on a deleteable button delete it...
  527.   if (FSpeedIndex < SpeedList->Count) {
  528.     SpeedList->Delete(FSpeedIndex);
  529.  
  530.     // ...but if it is beyond any possible deleteable button
  531.     // just set cursor to beyond last button in speedbar.
  532.     if (FSpeedIndex > SpeedList->Count)
  533.       FSpeedIndex = SpeedList->Count;
  534.  
  535.     Speedbar->Invalidate();
  536.   }
  537. } // end of TAppExpert::RemoveClick()
  538.  
  539. //========================================== TAppExpert =========
  540. // Return an index into SpeedList from the TPoint. If there is
  541. //  no speedbutton at TPoint position, return -1.
  542. int __fastcall TAppExpert::SpeedButtonAtPos(const tagPOINT &Pos)
  543. {
  544.   for (int i=0; i < SpeedList->Count; i++)
  545.   {
  546.     TRect R = SpeedButtonRect(i);
  547.     if (PtInRect((RECT*)&R, Pos))
  548.     {
  549.       return i;
  550.     }
  551.   }
  552.  
  553.   return -1;
  554. } // end of TAppExpert::SpeedButtonAtPos()
  555.  
  556. //========================================== TAppExpert =========
  557. // The mouse was clicked in the Speedbar area. If the cursor is
  558. //  over a speebutton, hilight it otherwise hilight the last
  559. //  speedbutton in the list.
  560. void __fastcall TAppExpert::SpeedMouseDown(TObject *Sender,
  561.                                 TMouseButton Button,
  562.                                 TShiftState Shift,
  563.                                 Integer X, Integer Y)
  564. {
  565.   // Get the index of the speedbutton under the cursor and...
  566.   int Index = SpeedButtonAtPos(Point(X, Y));
  567.  
  568.   // ...if there is one there make it current else set current
  569.   // index to last speedbutton in list and...
  570.   if (Index != -1)
  571.     FSpeedIndex = Index;
  572.   else
  573.     FSpeedIndex = SpeedList->Count;
  574.  
  575.   // ...update for hilite.
  576.   Speedbar->Invalidate();
  577. } // end of TAppExpert::SpeeMouseDown()
  578.  
  579. //========================================== TAppExpert =========
  580. void __fastcall TAppExpert::BrowseClick(TObject *Sender)
  581. {
  582.   TSelectDirOpts tso;
  583.   tso << sdAllowCreate << sdPrompt << sdPerformCreate;
  584.  
  585.   String d = AppPath->Text;
  586.   if (SelectDirectory(d, tso, NULL))
  587.     AppPath->Text = d;
  588. } // end of TAppExpert::BrowseClick()
  589.  
  590. //========================================== TAppExpert =========
  591. void __fastcall TAppExpert::SamplePaint(TObject *Sender)
  592. {
  593.   if (SampleBmp != NULL)
  594.     Sample->Canvas->Draw(0, 0, SampleBmp);
  595. } // end of TAppExpert::SamplePaint()
  596.  
  597. //========================================== TAppExpert =========
  598. void __fastcall TAppExpert::FormCreate(TObject *Sender)
  599. {
  600.   SpeedList            = new TList;
  601.   ButtonList           = new TList;
  602.   Offscreen            = new Graphics::TBitmap;
  603.   Offscreen->Width     = Speedbar->Width;
  604.   Offscreen->Height    = Speedbar->Height;
  605.   SpeedPointer         = new Graphics::TBitmap;
  606.   SpeedPointer->Handle = LoadBitmap(HInstance, "SPEEDPOINTER");
  607.   SampleBmp            = new Graphics::TBitmap;
  608.  
  609.   // Fill the MenuItemList with the speedbuttons.
  610.   TButtonImage *ButtonImage;
  611.   for (long ID=sMenuItemTextBase;
  612.        ID < sMenuItemTextBase + MenuItemCount; ID++)
  613.   {
  614.     ButtonImage            = new TButtonImage;
  615.     ButtonImage->NumGlyphs = 2;
  616.     ButtonImage->BitmapID  = ID;
  617.     ButtonList->Add(ButtonImage);
  618.   }
  619.  
  620.   // This is required to prevent the Speedbar from erasing its
  621.   // background each time it paints.  This dramatically reduces
  622.   // (eliminates) any flicker when painting (try commenting
  623.   // out this line to see the difference).
  624.   Speedbar->ControlStyle << csOpaque;
  625.  
  626.   PageControl->ActivePage = PageControl->Pages[FirstPage];
  627.   SampleBmp->Handle = LoadBitmap(HInstance, SampleBitmaps[FirstPage]);
  628.  
  629.   RefreshButtons();
  630. } // end of TAppExpert::FormCreate()
  631.  
  632. //========================================== TAppExpert =========
  633. void __fastcall TAppExpert::FormDestroy(TObject *Sender)
  634. {
  635.   ButtonList->Clear();
  636.   delete ButtonList;
  637.   delete SpeedList;
  638.   delete SpeedPointer;
  639.   delete Offscreen;
  640.   delete SampleBmp;
  641. } // end of TAppExpert::FormDestroy()
  642.  
  643.  
  644. //=========================================[ TButtonImage ]======
  645. // TButtonImage
  646. __fastcall TButtonImage::TButtonImage(void)
  647. {
  648.   bmFBitmap = new Graphics::TBitmap;
  649.   FNumGlyphs = 1;
  650. }
  651.  
  652. //=========================================[ TButtonImage ]======
  653. __fastcall TButtonImage::~TButtonImage(void)
  654. {
  655.   delete bmFBitmap;
  656. }
  657.  
  658. //========================================= TButtonImage ========
  659. void __fastcall TButtonImage::SetBitmapID(long Value)
  660. {
  661.   if (FBitmapID != Value)
  662.   {
  663.     FBitmapID = Value;
  664.     bmFBitmap->Handle = LoadBitmap(HInstance, (char*)FBitmapID);
  665.   }
  666. } // end of TButtonImage::SetBitmapID()
  667.  
  668. //========================================= TButtonImage ========
  669. void __fastcall TButtonImage::Draw(TCanvas *Canvas, int x, int y)
  670. {
  671.   TColor SavePen   = Canvas->Pen->Color;
  672.   TColor SaveBrush = Canvas->Brush->Color;
  673.  
  674.   TRect Target = DrawButtonFace(Canvas, Bounds(x, y,
  675.                                 DefaultButtonSize.x,
  676.                                 DefaultButtonSize.y), 1, bsWin31,
  677.                                 False, False, False);
  678.  
  679.   // draw bitmap
  680.   int bx = bmFBitmap->Width / FNumGlyphs;
  681.   if (bx > 0)
  682.   {
  683.     Target = Bounds(x, y, bx, bmFBitmap->Height);
  684.     OffsetRect((RECT*)&Target, (DefaultButtonSize.x /2)-(bx/2),
  685.                (DefaultButtonSize.y / 2) - (bmFBitmap->Height/2));
  686.     TRect Source = Bounds(0, 0, bx, bmFBitmap->Height);
  687.     Canvas->BrushCopy(Target, bmFBitmap, Source,
  688.                       bmFBitmap->Canvas->Pixels[0][bmFBitmap->Height-1]);
  689.   }
  690.  
  691.   Canvas->Pen->Color   = SavePen;
  692.   Canvas->Brush->Color = SaveBrush;
  693. } // end of TButtonImage::Draw()
  694.  
  695. //--- FILE FILTER LIST CONTROLS ---------------------------------<<
  696.  
  697. //=========================================== TAppExpert ========
  698. // Draw the file extension list box.
  699. void __fastcall TAppExpert::DrawExtension(TWinControl *Control,
  700.                                           Integer Index,
  701.                                           const TRect &Rect,
  702.                                           TOwnerDrawState State)
  703. {
  704.   // Find the separator in the string and...
  705.   int P = ExtListBox->Items->Strings[Index].Pos("|");
  706.  
  707.   // ...adjust the rectangle so we draw only the left "column".
  708.   TRect R = Rect;
  709.   R.Right = R.Left + ExtHeader->SectionWidth[0];
  710.  
  711.   // Draw the filter description and...
  712.   char C[255];
  713.   String S = ExtListBox->Items->Strings[Index].SubString(1, P - 1);
  714.   ExtTextOut((void*)ExtListBox->Canvas->Handle, R.Left, R.Top,
  715.              ETO_CLIPPED | ETO_OPAQUE, (RECT*)&R, StrPCopy(C, S),
  716.              S.Length(), NULL);
  717.  
  718.   // ...move the rectangle to the next column and draw the
  719.   // file extensions.
  720.   R.Left = R.Right;
  721.   R.Right = Rect.Right;
  722.   S = ExtListBox->Items->Strings[Index].SubString(P + 1, 255);
  723.   ExtTextOut((void*)ExtListBox->Canvas->Handle, R.Left, R.Top,
  724.              ETO_CLIPPED | ETO_OPAQUE, (RECT*)&R, StrPCopy(C, S),
  725.              S.Length(), NULL);
  726. } // end of TAppExpert::DrawEstension()
  727.  
  728. //========================================== TAppExpert =========
  729. void __fastcall TAppExpert::HeaderSized(TObject *Sender,
  730.                                         Integer ASection,
  731.                                         Integer AWidth)
  732. {
  733.   ExtListBox->Invalidate();
  734. } // end of TAppExpert::HeaderSized()
  735.  
  736. //=========================================== TAppExpert ========
  737. void __fastcall TAppExpert::AddClick(TObject *Sender)
  738. {
  739. //  String Filter;
  740.  
  741.   String Filter(""); // = "";
  742.   if (EditFilterInfo(Filter))
  743.     ExtListBox->Items->Add(Filter);
  744. } // end of TAppExpert::AddClick()
  745.  
  746. //========================================== TAppExpert =========
  747. void __fastcall TAppExpert::EditClick(TObject *Sender)
  748. {
  749.   String Filter;
  750.  
  751.   if (ExtListBox->ItemIndex > -1)
  752.   {
  753.     Filter = ExtListBox->Items->Strings[ExtListBox->ItemIndex];
  754.     if (EditFilterInfo(Filter))
  755.       ExtListBox->Items->Strings[ExtListBox->ItemIndex] = Filter;
  756.   }
  757. } // end of TAppExpert::EditClick()
  758.  
  759. //========================================== TappExpert =========
  760. void __fastcall TAppExpert::DeleteClick(TObject *Sender)
  761. {
  762.   if (ExtListBox->ItemIndex > -1)
  763.     ExtListBox->Items->Delete(ExtListBox->ItemIndex);
  764. } // end of TAppExpert::DeleteClick()
  765.  
  766. //========================================= TAppExpert ==========
  767. void __fastcall TAppExpert::MoveClick(TObject *Sender)
  768. {
  769.   int Delta;
  770.   int NewPos;
  771.  
  772.   if (ExtListBox->ItemIndex != -1)
  773.   {
  774.     if (Sender == UpButton)
  775.       Delta = -1;
  776.     else
  777.       if (Sender == DownButton)
  778.         Delta = 1;
  779.       else
  780.         Delta = 0;
  781.  
  782.     if (Delta != 0)
  783.     {
  784.       NewPos = ExtListBox->ItemIndex + Delta;
  785.       if (NewPos >= 0 && NewPos < ExtListBox->Items->Count)
  786.       {
  787.         ExtListBox->Items->Move(ExtListBox->ItemIndex, NewPos);
  788.         ExtListBox->ItemIndex = NewPos;
  789.       }
  790.     }
  791.   }
  792. } // end of TAppExpert::MoveClick()
  793.  
  794. //---------------------------------------------------------------
  795. //  Display file filter dialog box and get new file description
  796. //    and file filter type(s) as bar ('|") formatted AnsiString
  797. //    in 'Filter'. If dialog box was cancelled, return false else
  798. //    return true.
  799. bool __fastcall EditFilterInfo(String &Filter)
  800. {
  801.   bool result;
  802.  
  803.   try
  804.   {
  805.     auto_ptr<TFilterDlg> d(new TFilterDlg(Application));
  806.     d.get()->Filter = Filter;
  807.     result = d.get()->ShowModal() == mrOK;
  808.     if (result)
  809.       Filter = d.get()->Filter;
  810.  
  811.   } catch(...)
  812.   {
  813.   }
  814.  
  815.   return result;
  816. } // end of EditFilterInfo()
  817.  
  818. //--- SOURCE GENERATION FUNCTIONS -------------------------------<<
  819.  
  820. //---------------------------------------------------------------
  821. void _fastcall FmtWrite(TStream *Stream, char *Fmt,
  822.                         const TVarRec *Args, const int Args_Size)
  823. {
  824.   StrLFmt(cSourceBuffer, SourceBufferSize, Fmt, Args, Args_Size);
  825.  
  826.   if (snoop)
  827.     MessageBox(NULL, cSourceBuffer, "Snooper duper", MB_OK);
  828.  
  829.   Stream->Write((void*)cSourceBuffer, strlen(cSourceBuffer));
  830. } // end of FmtWrite()
  831.  
  832. //---------------------------------------------------------------
  833. void __fastcall WriteSnipet(TStream *Stream, TCodeSnipet Snipet)
  834. {
  835.   Stream->Write((void*)cCodeSnipets[Snipet],
  836.                 strlen(cCodeSnipets[Snipet]));
  837. } // end of WriteSnipet()
  838.  
  839. //---------------------------------------------------------------
  840. void __fastcall WriteIdent(TStream *Stream, long ResID,
  841.                            const String VarType)
  842. {
  843.   sprintf(cSourceBuffer, "%s%s *%s;\n", INDENT, VarType.c_str(),
  844.                                         LoadStr(ResID).c_str());
  845.   Stream->Write((void*)cSourceBuffer, strlen(cSourceBuffer));
  846. } // WriteIdent()
  847.  
  848. //---------------------------------------------------------------
  849. void __fastcall WriteMenuItems(TStream *Stream,
  850.                                TMainItems MenuIndex)
  851. {
  852.   for (int i=0; i<MenuItemCounts[MenuIndex]-1; i++)
  853.   {
  854.     WriteIdent(Stream,
  855.                sMenuItemNameBase+MenuItemOffsets[MenuIndex]+i,
  856.                "TMenuItem");
  857.   }
  858. } // end of WriteMenuItems()
  859.  
  860. //---------------------------------------------------------------
  861. void __fastcall WriteMethodDecl(TStream *Stream, long ResID)
  862. {
  863.   sprintf(cSourceBuffer, "%svoid __fastcall %s(TObject *Sender);",
  864.           INDENT, LoadStr(ResID).c_str());
  865.   Stream->Write(cSourceBuffer, strlen(cSourceBuffer));
  866.   Stream->Write(CRLF, 2);
  867. } // end of WriteMethodDecl()
  868.  
  869. //---------------------------------------------------------------
  870. void __fastcall WriteMethodHeader(TStream *Stream, long ResID)
  871. {
  872.   sprintf(cSourceBuffer,
  873.           "%s%svoid __fastcall T%s::%s(TObject *Sender)",
  874.           SEPARATOR, CRLF, LoadStr(sMainForm).c_str(),
  875.           LoadStr(ResID).c_str());
  876.   Stream->Write((void*)cSourceBuffer, strlen(cSourceBuffer));
  877. } // end of WriteMethodHeader()
  878.  
  879. //---------------------------------------------------------------
  880. void __fastcall WriteMenuMethodDecls(TStream *Stream,
  881.                                      TMainItems MenuIndex)
  882. {
  883.   for (int i=0; i<MenuItemCounts[MenuIndex]; i++)
  884.     WriteMethodDecl(Stream,
  885.                     sMenuProcNames+MenuItemOffsets[MenuIndex]+i);
  886. } // end of WriteMethodDecls()
  887.  
  888. //---------------------------------------------------------------
  889. void __fastcall WriteMenuMethods(TStream *Stream,
  890.                                  TMainItems MenuIndex,
  891.                                  TCodeSnipet BaseSnipet)
  892. {
  893.   TCodeSnipet snipet;
  894.  
  895.   int id = sMenuProcNames + MenuItemOffsets[MenuIndex];
  896.   for (int i=0; i<MenuItemCounts[MenuIndex]; i++)
  897.   {
  898.     WriteMethodHeader(Stream, id+i);
  899.     snipet = TCodeSnipet(i+BaseSnipet);
  900.     WriteSnipet(Stream, snipet);
  901.   }
  902. } // end of WriteMenuMethods()
  903.  
  904. //---------------------------------------------------------------
  905. TFileName* __fastcall GenerateProjectSource(TAppExpert *AppExpert)
  906. {
  907.   // Get the application expert's fully qualified specification
  908.   // (path\APPNAME.CPP).
  909.   TFileName *result = new TFileName;
  910.   *result = AppExpert->AppPath->Text;
  911.  
  912.   // If it is not slash terminated, slash terminate it and...
  913.   int rl = result->Length();
  914.   if (rl > 0)
  915.     if ((*result)[rl-1] != ':')
  916.       if ((*result)[rl-1] != '\\')
  917.         *result += "\\";
  918.  
  919.   // ...add application file name and a CPP extension.
  920.   *result += AppExpert->AppName->Text + ".CPP";
  921.  
  922.   // Open the project file stream and...
  923.   try
  924.   {
  925.     auto_ptr<TFileStream> projectFile(new TFileStream(*result,
  926.                                                       fmCreate));
  927.  
  928.     // ...write the usual WinMain() and app startup code.
  929.     sprintf(cSourceBuffer, cCodeSnipets[csMainImpl],
  930.             AppExpert->AppName->Text.c_str());
  931.     projectFile.get()->Write(cSourceBuffer, strlen(cSourceBuffer));
  932.   } catch(...)
  933.   {
  934.   }
  935.  
  936.   // Return the file spec to caller.
  937.   return result;
  938. } // end of GenerateProjectSource()
  939.  
  940. //---------------------------------------------------------------
  941. void __fastcall GenerateHdrSourceFile(TAppExpert *AppExpert)
  942. {
  943.   String      buttonName;
  944.   String      buttonText;
  945.  
  946.   // Create fully qualified name spec for the header module
  947.   // (i.e., path\main.h).
  948.   TFileName filename(AppExpert->AppPath->Text);
  949.   if (filename.Length() > 0 && (filename[filename.Length()] != ':' &&
  950.                                  filename[filename.Length()] != '\\'))
  951.     filename += '\\';
  952.  
  953.   // "main.h" in Strings.rc
  954.   filename += LoadStr(sHdrSourceFile);
  955.  
  956.   try
  957.   {
  958.     auto_ptr<TFileStream> stream(new TFileStream(filename, fmCreate));
  959.     WriteSnipet(stream.get(), csHdr1);
  960.     *cSourceBuffer = 0;
  961.  
  962.     // Create the menu declarations.
  963.     if (AppExpert->HasMenus())
  964.     {
  965.       WriteIdent(stream.get(), sMainMenu, "TMainMenu");
  966.       if (AppExpert->cbFileMenu->Checked)
  967.         WriteMenuItems(stream.get(), mmFile);
  968.       if (AppExpert->cbEditMenu->Checked)
  969.         WriteMenuItems(stream.get(), mmEdit);
  970.       if (AppExpert->cbWindowMenu->Checked)
  971.         WriteMenuItems(stream.get(), mmWindow);
  972.       if (AppExpert->cbHelpMenu->Checked)
  973.         WriteMenuItems(stream.get(), mmHelp);
  974.     }
  975.  
  976.     // Create any variable declarations
  977.     if (AppExpert->cbStatusLine->Checked)
  978.       WriteIdent(stream.get(), sStatusLine, "TStatusBar");
  979.  
  980.     if (AppExpert->cbFileMenu->Checked)
  981.     {
  982.       WriteIdent(stream.get(), sOpenDialog, "TOpenDialog");
  983.       WriteIdent(stream.get(), sSaveDialog, "TSaveDialog");
  984.       WriteIdent(stream.get(), sPrintDialog, "TPrintDialog");
  985.       WriteIdent(stream.get(), sPrintSetupDialog, "TPrinterSetupDialog");
  986.     }
  987.  
  988.     // If there are any speedbuttons specified...
  989.     if (AppExpert->SpeedButtonCount > 0)
  990.     {
  991.       // Write the TPanel data member ("TPanel *SpeedBar") to the
  992.       // stream and...
  993.       WriteIdent(stream.get(), sSpeedBar, "TPanel");
  994.  
  995.       // ...compose the format string for a SpeedButton data
  996.       // member ("TSpeedButton *SpeedButton%d  // %s").
  997.       buttonName = (String)INDENT + "TSpeedButton *" +
  998.                            LoadStr(sSpeedButton) +
  999.                            ";  // %s" + CRLF;
  1000.  
  1001.       // For every speed button specified in the ButtonList,...
  1002.       int buttonID = 1;
  1003.       for (int i=0; i < AppExpert->SpeedButtonCount; i++)
  1004.       {
  1005.         // ...excluding speedbutton entries that are not used,...
  1006.         if (AppExpert->SpeedButtonID[i] > -1)
  1007.         {
  1008.           // ...get the id for the button and compose the
  1009.           // speed button data member's string and write it out
  1010.           // to the stream.
  1011.           buttonText = LoadStr(AppExpert->SpeedButtonID[i]);
  1012.           sprintf(cSourceBuffer, buttonName.c_str(), buttonID,
  1013.                   buttonText.c_str());
  1014.           stream.get()->Write(cSourceBuffer, strlen(cSourceBuffer));
  1015.           buttonID++;
  1016.         }
  1017.       }
  1018.     }
  1019.  
  1020.     // Generate method declarations.
  1021.     if (AppExpert->cbStatusLine->Checked &&
  1022.         AppExpert->cbHints->Checked)
  1023.     {
  1024.       WriteMethodDecl(stream.get(), sFormCreateProc);
  1025.       WriteMethodDecl(stream.get(), sShowHelpProc);
  1026.     }
  1027.  
  1028.     if (AppExpert->cbFileMenu->Checked)
  1029.       WriteMenuMethodDecls(stream.get(), mmFile);
  1030.     if (AppExpert->cbEditMenu->Checked)
  1031.       WriteMenuMethodDecls(stream.get(), mmEdit);
  1032.     if (AppExpert->cbWindowMenu->Checked)
  1033.       WriteMenuMethodDecls(stream.get(), mmWindow);
  1034.     if (AppExpert->cbHelpMenu->Checked)
  1035.       WriteMenuMethodDecls(stream.get(), mmHelp);
  1036.  
  1037.     WriteSnipet(stream.get(), csHdr2);
  1038.  
  1039.   } catch(...)
  1040.   {
  1041.   }
  1042. } // end of GenerateHdrSourceFile()
  1043.  
  1044. //---------------------------------------------------------------
  1045. void __fastcall GenerateMainSourceFile(TAppExpert *AppExpert) {
  1046.   String ButtonName;
  1047.   String ButtonText;
  1048.  
  1049.   // Create fully qualified name spec for the main() module
  1050.   // (i.e., path\main.cpp).
  1051.   TFileName filename(AppExpert->AppPath->Text);
  1052.   if (filename.Length() > 0 && (filename[filename.Length()] != ':' &&
  1053.                                 filename[filename.Length()] != '\\'))
  1054.     filename += '\\';
  1055.  
  1056.   filename += LoadStr(sMainSourceFile);
  1057.  
  1058.   // Create/open file,
  1059.   try
  1060.   {
  1061.     auto_ptr<TFileStream> stream(new TFileStream(filename, fmCreate));
  1062.     WriteSnipet(stream.get(), csProgram);
  1063.     *cSourceBuffer = 0;
  1064.  
  1065.     // Write code implementations.
  1066.     if (AppExpert->cbStatusLine->Checked &&
  1067.         AppExpert->cbHints->Checked)
  1068.     {
  1069.       WriteMethodHeader(stream.get(), sFormCreateProc);
  1070.       WriteSnipet(stream.get(), csFormCreateProc);
  1071.       WriteMethodHeader(stream.get(), sShowHelpProc);
  1072.       WriteSnipet(stream.get(), csShowHelpProc);
  1073.     }
  1074.  
  1075.     // Create menu variables...
  1076.     if (AppExpert->cbFileMenu->Checked)
  1077.       WriteMenuMethods(stream.get(), mmFile, csFileNewProc);
  1078.  
  1079.     if (AppExpert->cbEditMenu->Checked)
  1080.       WriteMenuMethods(stream.get(), mmEdit, csEditUndoProc);
  1081.  
  1082.     if (AppExpert->cbWindowMenu->Checked)
  1083.       WriteMenuMethods(stream.get(), mmWindow, csWindowTileProc);
  1084.  
  1085.     if (AppExpert->cbHelpMenu->Checked)
  1086.       WriteMenuMethods(stream.get(), mmHelp, csHelpContentsProc);
  1087.  
  1088.     String s = (String)SEPARATOR + CRLF;
  1089.     FmtWrite(stream.get(), s.c_str(), OPENARRAY(TVarRec, (NULL)));
  1090.   } catch(...)
  1091.   {
  1092.   }
  1093. } // end of GenerateMainSourceFile()
  1094.  
  1095. //---------------------------------------------------------------
  1096. void __fastcall BinToHex(char *Binary, char *Text, int Count)
  1097. {
  1098.   char *HexChars = "0123456789ABCDEF";
  1099.   int              i;
  1100.  
  1101.   // For number of bytes specified in 'Count'..."
  1102.   for (i=0; i < Count; i++)
  1103.   {
  1104.     // ...strip lo nibble, move hi to lo, convert to ASCII hex
  1105.     // and stuff in buffer.
  1106.     *Text = HexChars[(Binary[i] & 0xF0) >> 4];
  1107.     Text++;
  1108.  
  1109.     // Strip hi nibble of next byte, convert to ASCII hex and
  1110.     // stuff in buffer.
  1111.     *Text = HexChars[Binary[i] & 0x0F];
  1112.     Text++;
  1113.   }
  1114. } // end of BinToHex()
  1115.  
  1116. //---------------------------------------------------------------
  1117. void __fastcall WriteBinaryAsText(TStream *Input, TStream *Output)
  1118. {
  1119.   const int BytesPerLine = 32;
  1120.   bool      MultiLine;
  1121.   int       i;
  1122.   long      Count;
  1123.   char      Buffer[BytesPerLine];
  1124.   char      Text[BytesPerLine * 2 - 1];
  1125.  
  1126.   // Get the size of the input buffer and...
  1127.   Count = Input->Size;
  1128.  
  1129.   // ...if its longer than our max line length (32 bytes)
  1130.   // flag it a multiline buffer.
  1131.   MultiLine = Count > BytesPerLine;
  1132.  
  1133.   // Convert buffer size to hex and write to stream.
  1134.   BinToHex((char*)&Count, Text, 4);
  1135.   Output->Write(Text, 4 * 2);
  1136.  
  1137.   while(Count > 0)
  1138.   {
  1139.     if (MultiLine)
  1140.       Output->Write((void*)CRLF, 2);
  1141.  
  1142.     // If we have at least 32 bytes left to write write 32 bytes...
  1143.     if (Count >= BytesPerLine)
  1144.       i = BytesPerLine;
  1145.     else
  1146.  
  1147.       // ...else write the last of the bytes.
  1148.       i = Count;
  1149.  
  1150.     // Get the bytes, convert 'um to ASCII hex and write 'um out.
  1151.     Input->Read(Buffer, i);
  1152.     BinToHex(Buffer, Text, i);
  1153.     Output->Write(Text, i * 2);
  1154.  
  1155.     // Adjust bytes to write for next run.
  1156.     Count -= i;
  1157.   }
  1158. } // end of WriteBinaryAsText()
  1159.  
  1160. //---------------------------------------------------------------
  1161. void __fastcall WriteGlyphData(TStream *Stream, long BitmapID)
  1162. {
  1163.   try
  1164.   {
  1165.     // Create a bitmap and load with the specified glyph.
  1166.     auto_ptr<Graphics::TBitmap> bitmap(new Graphics::TBitmap);
  1167.     bitmap.get()->Handle = LoadBitmap(HInstance, (char*)BitmapID);
  1168.  
  1169.     // Stream the bitmap to a memory stream, and the write that
  1170.     // stream as text.
  1171.     try
  1172.     {
  1173.       auto_ptr<TMemoryStream> memory(new TMemoryStream);
  1174.       bitmap.get()->SaveToStream(memory.get());
  1175.       memory.get()->Position = 0;
  1176.       WriteBinaryAsText(memory.get(), Stream);   // 1 invokation
  1177.     } catch(...)
  1178.     {
  1179.     }
  1180.   } catch(...)
  1181.   {
  1182.   }
  1183.  
  1184.   FmtWrite(Stream, "}\nend\n", OPENARRAY(TVarRec, (NULL)));
  1185. } // end of WriteGlyphData()
  1186.  
  1187. //---------------------------------------------------------------
  1188. void __fastcall GenerateMainFormFile(TAppExpert *AppExpert)
  1189. {
  1190.   int    buttonWidth = 25;
  1191.   int    spaceWidth = 4;
  1192.   String filter;
  1193.   int    buttonNumber;
  1194.   int    buttonID;
  1195.   String buttonMethod;
  1196.   String buttonHint;
  1197.   int    buttonX;
  1198.   int    i;
  1199.  
  1200.   // Compose a slash terminated path spec for the text represent-
  1201.   // ation of the application's form (MAIN.TXT) and the target
  1202.   // form itself (MAIN.DFM).
  1203.   TFileName textName(AppExpert->AppPath->Text);
  1204.   if (textName.Length() > 0 && (textName[textName.Length()] != ':' ||
  1205.                                 textName[textName.Length()] != '\\'))
  1206.     textName += '\\';
  1207.  
  1208.   // Compose the full file spec for the form and its text
  1209.   // representation then...
  1210.   TFileName formName(textName + LoadStr(sMainFormFile));
  1211.   textName += LoadStr(sMainFormText);
  1212.  
  1213.   try
  1214.   {
  1215.     // ...open/create them.
  1216.     auto_ptr<TFileStream> textStream(new TFileStream(textName,
  1217.                                                      fmCreate));
  1218.     auto_ptr<TFileStream> formStream(new TFileStream(formName,
  1219.                                                      fmCreate));
  1220.  
  1221.     // Write the prologue of the form resource:
  1222.     //  object MainForm: TMainForm
  1223.     //     Left = 214
  1224.     //     Top = 112
  1225.     //     Width = 409
  1226.     //     Height = 249
  1227.     //     Caption = 'MainForm'
  1228.     //     Font.Color = clWindowText
  1229.     //     Font.Height = -11
  1230.     //     Font.Name = 'MS Sans Serif'
  1231.     //     PixelsPerInch = 96
  1232.     //     TextHeight = 13
  1233.     WriteSnipet(textStream.get(), csForm);
  1234.  
  1235.     // If this is to be an MDI app, init style member:
  1236.     //     FormStyle = fsMDIForm
  1237.     if (AppExpert->cbMDIApp->Checked) {
  1238.       WriteSnipet(textStream.get(), csFormMDI);
  1239.     }
  1240.  
  1241.     // If it has menus, init the menu member:
  1242.     //     Menu = MainMenu
  1243.     if (AppExpert->HasMenus())
  1244.       WriteSnipet(textStream.get(), csFormMenu);
  1245.  
  1246.     // If hints are enabled...
  1247.     if (AppExpert->cbHints->Checked)
  1248.     {
  1249.  
  1250.       // ...enable hints like this:...
  1251.       //   ShowHint = True
  1252.       WriteSnipet(textStream.get(), csHints);
  1253.  
  1254.       // ...and if both hints and status line are selected:
  1255.       //   OnCreate = FormCreate
  1256.       if (AppExpert->cbStatusLine->Checked)
  1257.         WriteSnipet(textStream.get(), csCreateMethod);
  1258.     }
  1259.  
  1260.     // If we have any menus selected, write...
  1261.     if (AppExpert->HasMenus())
  1262.     {
  1263.       // ...the menu object prologue...
  1264.       //   object MainMenu: TMainMenu
  1265.       //     Left = 220
  1266.       //     Top = 40
  1267.       WriteSnipet(textStream.get(), csMenuObject);
  1268.  
  1269.       // ...followed by the resource statements for any selected
  1270.       // menu(s)...
  1271.       if (AppExpert->cbFileMenu->Checked)
  1272.         WriteSnipet(textStream.get(), csFileMenuObject);
  1273.       if (AppExpert->cbEditMenu->Checked)
  1274.         WriteSnipet(textStream.get(), csEditMenuObject);
  1275.       if (AppExpert->cbWindowMenu->Checked)
  1276.         WriteSnipet(textStream.get(), csWindowMenuObject);
  1277.       if (AppExpert->cbHelpMenu->Checked) {
  1278.         WriteSnipet(textStream.get(), csHelpMenuObject);
  1279.       }
  1280.  
  1281.       // ...and terminate section.
  1282.       FmtWrite(textStream.get(), "  end\n",
  1283.                OPENARRAY(TVarRec, (NULL)));
  1284.  
  1285.       // If the file menu was selected we need to deal with the
  1286.       // file filters.
  1287.       if (AppExpert->cbFileMenu->Checked)
  1288.       {
  1289.         // Concatenate all listed filters with bar ('|') separator.
  1290.         filter = "";
  1291.         for (i=0; i < AppExpert->ExtListBox->Items->Count; i++)
  1292.           filter += AppExpert->ExtListBox->Items->Strings[i] + "|";
  1293.  
  1294.         // Eliminate the last bar from the conactenated string of
  1295.         // filters and...
  1296.         if (filter.SubString(1, filter.Length()) == "|")
  1297.           filter.Delete(1, filter.Length());
  1298.  
  1299.         // ...format and write the filters string to the Open and
  1300.         // Save Dialog box resource templates.
  1301.         FmtWrite(textStream.get(), cCodeSnipets[csOpenDialogObject],
  1302.                  OPENARRAY(TVarRec, (filter)));
  1303.         FmtWrite(textStream.get(), cCodeSnipets[csSaveDialogObject],
  1304.                  OPENARRAY(TVarRec, (filter)));
  1305.         WriteSnipet(textStream.get(), csPrintDialogObject);
  1306.         WriteSnipet(textStream.get(), csPrintSetupDialogObject);
  1307.       }
  1308.     }
  1309.  
  1310.     // If selected, write the status line object.
  1311.     if (AppExpert->cbStatusLine->Checked)
  1312.       WriteSnipet(textStream.get(), csStatusLineObject);
  1313.  
  1314.     // Create speedbuttons.
  1315.     if (AppExpert->SpeedButtonCount > 0)
  1316.     {
  1317.       // object SpeedBar: TPanel
  1318.       //    Align = alTop
  1319.       //    Height = 33
  1320.       WriteSnipet(textStream.get(), csSpeedbarObject);
  1321.  
  1322.       buttonNumber = 0;
  1323.       buttonX      = 8;  // x coordinate of speedbutton
  1324.       for (i=0; i < AppExpert->SpeedButtonCount; i++)
  1325.       {
  1326.         if (AppExpert->SpeedButtonID[i] > -1)
  1327.         {
  1328.           buttonNumber++;
  1329.           buttonID = AppExpert->SpeedButtonID[i]-sMenuItemTextBase;
  1330.           buttonMethod = LoadStr(buttonID + sMenuProcNames);
  1331.           buttonHint = LoadStr(buttonID + sHintBase);
  1332.  
  1333.           // csSpeedButtonObject:
  1334.           //    object SpeedButton%d: TSpeedButton
  1335.           //      Left = %d
  1336.           //      Top = 4
  1337.           //      Width = 25
  1338.           //      Height = 25
  1339.           //      OnClick = %s
  1340.           //      Hint = '%s'
  1341.           //      NumGlyphs = 2
  1342.           //      Glyph.Data = {
  1343.           sprintf(cSourceBuffer, cCodeSnipets[csSpeedButtonObject],
  1344.                   buttonNumber, buttonX, buttonMethod.c_str(),
  1345.                   buttonHint.c_str());
  1346.           textStream.get()->Write((void*)cSourceBuffer,
  1347.                                   strlen(cSourceBuffer));
  1348.           WriteGlyphData(textStream.get(), buttonID + 100);
  1349.           buttonX += buttonWidth-1;
  1350.         }
  1351.         else
  1352.         {
  1353.           buttonX += spaceWidth;
  1354.         }
  1355.       }
  1356.       FmtWrite(textStream.get(), "  end\n",
  1357.                OPENARRAY(TVarRec, (NULL)));
  1358.     }
  1359.  
  1360.     FmtWrite(textStream.get(), "end\n", OPENARRAY(TVarRec, (NULL)));
  1361.  
  1362.     // reset the text stream for conversion
  1363.     textStream.get()->Position = 0;
  1364.  
  1365.     try
  1366.     {
  1367.       ObjectTextToResource(textStream.get(), formStream.get());
  1368.     } catch(...)
  1369.     {
  1370.     }
  1371.  
  1372.   } catch(...)
  1373.   {
  1374.   }
  1375. } // end of GenerateMainFormFile()
  1376.  
  1377. //--- INITIALIZATION AND DEINITIALIZATION FUNCTIONS -------------<<
  1378.  
  1379. //---------------------------------------------------------------
  1380. void __fastcall InitCodeGeneration(void)
  1381. {
  1382.   // Allocate the composition buffer,...
  1383.   cSourceBuffer = new char[SourceBufferSize];
  1384.  
  1385.   // ...find out how much data is in the code snippets resource...
  1386.   int ResourceSize = SizeofResource(HInstance,
  1387.                                     FindResource(HInstance,
  1388.                                                  "SNIPETS",
  1389.                                                  RT_RCDATA));
  1390.  
  1391.   // ...and get them into global memory.
  1392.   hCodeResource = (int*)LoadResource(HInstance,
  1393.                                      FindResource(HInstance,
  1394.                                                   "SNIPETS",
  1395.                                                   RT_RCDATA));
  1396.  
  1397.   // Keep 'um from moving around,...
  1398.   char *cResourcePtr = (char*)LockResource(hCodeResource);
  1399.  
  1400.   // ...allocate some local memory for them and...
  1401.   cResourceBuffer = new char[ResourceSize];
  1402.  
  1403.   // ...transfer the global data to the local allocation.
  1404.   memcpy(cResourceBuffer, cResourcePtr, ResourceSize);
  1405.  
  1406.   // Make ASCIIZ strings out of the snippets by replacing bars
  1407.   // ('|') with zeros and load into snippets pointer array.
  1408.   int j = 0;
  1409.   int t = 0;
  1410.   char *cText = cResourceBuffer;
  1411.   for (int i=0; i < ResourceSize; i++)
  1412.   {
  1413.     if (cText[i] == '|') {
  1414.       cText[i] = 0;
  1415.       cCodeSnipets[j++] = &(cText[t]);
  1416.       t = i+1;
  1417.     }
  1418.   }
  1419. } // end of InitCodeGeneration()
  1420.  
  1421. //---------------------------------------------------------------
  1422. void __fastcall DoneCodeGeneration(void)
  1423. {
  1424.   delete cSourceBuffer;
  1425.   UnlockResource(hCodeResource);
  1426.   FreeResource(hCodeResource);
  1427. //delete cResourceBuffer;
  1428. } // end of DoneCodeGeneration()
  1429.  
  1430. //*****************************************************************
  1431. // interface void
  1432. void __fastcall ApplicationExpert(TIToolServices *ToolServices)
  1433. {
  1434.   String    usesClause;
  1435.   TFileName projectName;
  1436.  
  1437.   try
  1438.   {
  1439.     // Create an application expert and...
  1440.     auto_ptr<TAppExpert> d(new TAppExpert(Application));
  1441.  
  1442.     // ...do user input.
  1443.     if (d.get()->ShowModal() == mrOK) {
  1444.  
  1445.       // If that's good set it up for execution.
  1446.       InitCodeGeneration();
  1447.  
  1448.       try
  1449.       {
  1450.         projectName = ExpandFileName(*GenerateProjectSource(d.get()));
  1451.         GenerateHdrSourceFile(d.get());
  1452.         GenerateMainSourceFile(d.get());
  1453.         GenerateMainFormFile(d.get());
  1454.       } catch(...)
  1455.       {
  1456.       }
  1457.  
  1458.       DoneCodeGeneration();
  1459.  
  1460.       // open the new project
  1461.       if (ToolServices != NULL && ToolServices->CloseProject())
  1462.         ToolServices->OpenProject(projectName);
  1463.     }
  1464.   } catch(...)
  1465.   {
  1466.   }
  1467. } // end of ApplicationExpert()
  1468.  
  1469.